<template>
	<el-table v-loading="loading" :border="border" :data="tableData" v-bind="elTableProps" class="v-table"
		@selection-change="onSelectionChange" @row-click="$emit('row-click', $event)" :key="count" :row-key="rowKey">
		<template #empty>
			<el-empty description="暂无数据" />
		</template>

		<el-table-column v-if="hasSelection" type="selection" reserve-selection width="50"></el-table-column>
		<el-table-column v-for="item in tableOptions" :key="item.key || item.title" :column-key="item.key || item.title"
			:label="item.title" :prop="item.key" :align="item.align || item.headerAlign || 'center'"
			:header-align="item.headerAlign || item.align || 'center'" :show-overflow-tooltip="!!item.tooltip"
			:width="item.width" v-auth="item.auth" resizable :filters="item.filters ? item.filters.list : undefined"
			:filter-method="
				item.filters
					? item.filters.method
						? item.filters.method
						: (value, row) => filterMethod(value, row, item)
					: undefined
			" :fixed="item.fixed || false">
			<template #default="{ row, $index }">
				<slot v-if="hasSlot(item.key)" :name="item.key || item.title" :row="row" :$index="$index" v-bind="row"></slot>
				<v-column v-else :data="row" :column="item" :index="$index"></v-column>
			</template>
		</el-table-column>
	</el-table>
	<template v-if="pagination">
		<div class="pagination">
			<el-pagination class="el-pagination" background layout="total,sizes,prev,pager,next,jumper"
				:current-page="paginationCurrent" :page-sizes="[10, 15, 20, 30, 40, 50, 70, 100]" :page-size="paginationSize"
				:total="paginationTotal" @size-change="$emit('size-change', $event)"
				@current-change="$emit('current-change', $event)">
			</el-pagination>
		</div>
	</template>
</template>

<script setup>
import { shallowRef, useSlots, watch } from "vue"
import VColumn from "./column/index.vue"

const props = defineProps({
	data: {
		type: Object,
	},
	options: {
		type: Array,
	},
	loading: {
		type: Boolean,
		default: false,
	},
	pagination: {
		type: Boolean,
		default: true,
	},
	elTableProps: {
		type: Object,
		default: () => ({}),
	},
	modelValue: {
		type: Array,
		default: () => [],
	},
	hasSelection: {
		type: Boolean,
		default: true,
	},
	rowKey: {
		type: String,
	},
	border: {
		type: Boolean,
		default: true,
	},
})

const emits = defineEmits(["update:modelValue", "selection-change", "current-change", "size-change", "row-click"])

const tableData = computed(() => props.data.data)
const paginationCurrent = computed({
	get() {
		if (props.pagination) {
			return props.data.current
		}
		return 1
	},
	set(value) {
		if (props.pagination) {
			props.data.current = value
		}
	},
})
const paginationSize = computed({
	get() {
		if (props.pagination) {
			return props.data.size
		}
		return 1
	},
	set(value) {
		if (props.pagination) {
			props.data.size = value
		}
	},
})
const paginationTotal = computed({
	get() {
		if (props.pagination) {
			return props.data.total
		}
		return 1
	},
	set(value) {
		if (props.pagination) {
			props.data.total = value
		}
	},
})

const tableOptions = computed(() =>
	props.options.filter(item => {
		let visible = true

		if (item.show !== undefined) {
			visible = item.show
		}
		if (visible && item.visible !== undefined) {
			visible = item.visible
		}

		return visible
	})
)

function onSelectionChange(selection) {
	emits("update:modelValue", selection)
	emits("selection-change", selection)
}
function filterMethod(value, row, item) {
	return row[item.key]?.toString().toLowerCase() === value.toLowerCase()
}

const slots = useSlots()
function hasSlot(key) {
	return !key || slots.hasOwnProperty(key)
}

const count = shallowRef(0)
watch(
	() => props.options,
	() => count.value++,
	{ deep: true }
)
</script>

<script>
export default {
	name: "v-table",
}
</script>

<style lang="scss" scoped>
.v-table {
	width: 100%;
}

.pagination {
	display: flex;
	justify-content: flex-end;
	align-items: center;
	margin-top: 20px;
}
</style>
